package com.example.user.service.map;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.framework.redis.core.util.RedisUtils;
import com.example.user.dal.dataobject.map.AreaDO;
import com.example.user.dal.mysql.map.AreaMapper;
import com.example.user.dal.redis.RedisKeyConstants;
import com.example.user.dto.AreaRespDto;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
public class AreaServiceImpl extends ServiceImpl<AreaMapper, AreaDO> implements AreaService {

    private static final Integer ROOT_PARENT_ID = 0;

    @Resource
    private AreaMapper areaMapper;

    private static final int EXPIRE_DAYS = 14;

    @Override
    public List<AreaRespDto> getAreaTree() {
        if (RedisUtils.hasKey(RedisKeyConstants.REDIS_AREA_KEY)) {
            return RedisUtils.getArray(RedisKeyConstants.REDIS_AREA_KEY, AreaRespDto.class);
        }
        List<AreaDO> areaEntities = areaMapper.selectList(null);
        if (ObjectUtil.isEmpty(areaEntities)) {
            return List.of();
        }
        List<AreaRespDto> result = buildAreaTree(areaEntities, ROOT_PARENT_ID);
        RedisUtils.set(RedisKeyConstants.REDIS_AREA_KEY, result, EXPIRE_DAYS, TimeUnit.DAYS);
        return result;
    }

    private List<AreaRespDto> buildAreaTree(List<AreaDO> areaEntities, Integer parentId) {
        if (ObjectUtil.isEmpty(areaEntities)) {
            return null; // 叶子节点的 children 设为 null
        }
        return areaEntities.stream()
                .filter(node -> Objects.equals(node.getParentId(), parentId))
                .map(node -> new AreaRespDto()
                        .setId(node.getAreaId())
                        .setName(node.getName())
                        .setParentId(node.getParentId())
                        .setChildren(buildAreaTree(areaEntities, node.getAreaId())))
                .collect(Collectors.toList());
    }
}